home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / mxlist.zip / AMORT2.PAS < prev    next >
Pascal/Delphi Source File  |  1993-01-04  |  10KB  |  328 lines

  1. Program AMORT2;
  2.  
  3. {$V-,N-,E- }
  4.  
  5. (*
  6.     This program uses the DMX unit to generate an amortization schedule.
  7.     It was recently updated for multiple mortgages and on-line help.
  8.  
  9.     Two DMX objects are used in this unit:
  10.  
  11.         The SelectWindow object uses a five-record editor to input
  12.         the financial parameters Year, Month, Amount, Rate, Years, and
  13.         Payment to calculate and compare five different loans schedules.
  14.         SELECTOR uses this object-type.
  15.  
  16.         The AmortWindow object is a descendant of DMXviewer, so as to
  17.         scroll through the table without allowing changes.  The DataAt
  18.         virtual function is modified to calculate each record as it
  19.         needs to be displayed.  This may be slow on an 8088 CPU, but
  20.         the advantage to this method is that the entire table does not need
  21.         to be kept in memory.
  22.         AMORT uses this object-type.
  23.  
  24.     The on-line help also makes use of DMX and object-oriented programming.
  25.     This is accomplished in the file DMX_LIST.PAS.
  26.  
  27.     This program is meant only as a demonstration for various uses of
  28.     the DMX objects.
  29.  
  30.     This program is designed for MONTHLY payments only.  BI-WEEKLY mortgages
  31.     have a radically different schedule --although you may certainly modify
  32.     this program to accommodate week numbers instead of month names.
  33.  
  34.  *)
  35.  
  36.  
  37. uses   Dos, Crt, DMX2, DMX_list;
  38.  
  39.  
  40. type   AmortRec     =  record
  41.                          Year       : word;
  42.                          MonthName  : string [12];
  43.                          Principal  : real;
  44.                          Interest   : real;
  45.                          Balance    : real;
  46.                        end;
  47.  
  48.        SelectRec    =  record
  49.                          Year,Month : word;
  50.                          Principal  : real;
  51.                          Interest   : real;
  52.                          Years      : word;
  53.                          Payment    : real;
  54.                        end;
  55.  
  56.        SelectWindow = object (DMXwindow)
  57.                         Info        : array [0..4] of SelectRec;
  58.                         procedure PickIt;
  59.                         procedure ZeroizeRecord (var Data );
  60.                                   virtual;
  61.                         procedure EvaluateField (RecNum : longint;
  62.                                                  CellNum,Line : word);
  63.                                   virtual;
  64.                       end;
  65.  
  66.        AmortWindow  = object (DMXviewer)
  67.                         linedata    :  AmortRec;
  68.                         Total       :  real;
  69.                         Rate        :  real;
  70.                         Payment     :  real;
  71.                         Years       :  word;
  72.                         Periods     :  word;
  73.                         FirstMonth  :  word;
  74.                         FirstYear   :  word;
  75.                         LastPayment :  word;
  76.                         LastTotal   :  real;
  77.  
  78.                         procedure Amortize (prin,interest :real; ys,y,m :word);
  79.                         function  DataAt (recnum : longint) : pointer;
  80.                                   virtual;
  81.                       end;
  82.  
  83.  
  84. const  maintitle   =  ' year   month           principal        interest          balance    ';
  85.        baseformat  =  ' WWWW │ ____________ ║($R,RRR,RRR.RR)│($R,RRR,RRR.RR)║($RR,RRR,RRR.RR)';
  86.  
  87.        spectitle   =  '  year   month       amount       rate    years     payment   ';
  88.        specformat  =  '  WWWW |  WW  ║ $rr,rrr,rrr.rr ║ %rr.rr |   WW  ║ $rrr,rrr.rr ';
  89.  
  90.        cr          =  #13;
  91.        Esc         =  #27;
  92.        F1          =  ';';
  93.        F9          =  'C';
  94.  
  95.        Months      :  array [0..11] of string [12] =
  96.                              ('January  ',
  97.                               'February ',
  98.                               'March    ',
  99.                               'April    ',
  100.                               'May      ',
  101.                               'June     ',
  102.                               'July     ',
  103.                               'August   ',
  104.                               'September',
  105.                               'October  ',
  106.                               'November ',
  107.                               'December ');
  108.  
  109.  
  110.  
  111. var    Key,ext     :  char;
  112.        DOScolors   :  word;          { original colors }
  113.  
  114.        SELECTOR    :  SelectWindow;  { selector object }
  115.        AMORT       :  AmortWindow;   { viewer object }
  116.  
  117.  
  118.   { ─────────────────────────────────────────────────────────────────────── }
  119.  
  120.  
  121. function  Radical (number,exponent : real) : real;
  122. { returns the value of number raised to the power of exponent }
  123. begin
  124.   Radical := exp (Ln (abs (number)) * abs (exponent))
  125. end;
  126.  
  127.  
  128.   { ─────────────────────────────────────────────────────────────────────── }
  129.  
  130.  
  131. function  AmortPMT (prin,interest,term : real) : real;
  132. { amount of the periodic payment on the loan }
  133. begin
  134.   AmortPMT := prin * (interest / (1 - (1 / (Radical (1 + interest,term)))));
  135. end;
  136.  
  137.  
  138.   { ─────────────────────────────────────────────────────────────────────── }
  139.  
  140.  
  141. function  AmortPRIN (pmt,interest,term : real) : real;
  142. { amount of the loan }
  143. begin
  144.   AmortPRIN := (pmt * (1 - (1 / (Radical (1 + interest,term))))) / interest;
  145. end;
  146.  
  147.  
  148.   { ─────────────────────────────────────────────────────────────────────── }
  149.  
  150.  
  151. function  AmortWindow.DataAt (recnum : longint) : pointer;
  152. { The original descendant of this method returns a pointer }
  153. { to where the record would be stored in memory.           }
  154. { This virtual method pretends to retrieve the next record }
  155. { by calculating the record contents in LINEDATA.          }
  156. { The function then returns a pointer to LINEDATA.         }
  157. { RECNUM is actually the payment number, minus zero.       }
  158. var  i,j  : word;
  159. begin
  160.   With linedata do
  161.     begin
  162.     If LastPayment <> recnum then
  163.       begin
  164.       If LastPayment > recnum then
  165.         begin
  166.         LastPayment := 0;
  167.         LastTotal   := Total;
  168.         end
  169.        else
  170.         Inc (LastPayment);
  171.       For i := LastPayment to recnum do
  172.         begin
  173.         Interest   :=  Rate * LastTotal;
  174.         Principal  :=  Payment - Interest;
  175.         LastTotal  :=  LastTotal - Principal;
  176.         If recnum = pred (recordlimit) then
  177.           Balance := 0.0
  178.          else
  179.           Balance :=  LastTotal;
  180.         end;
  181.       LastPayment := recnum;
  182.       end;
  183.     Year       := ((recnum + FirstMonth) div 12) + FirstYear;
  184.     MonthName  :=  Months [(recnum + FirstMonth) mod 12];
  185.     end;
  186.  
  187.   DataAt := addr (linedata);
  188. end;
  189.  
  190.  
  191.   { ─────────────────────────────────────────────────────────────────────── }
  192.  
  193.  
  194. procedure AmortWindow.Amortize (prin,interest : real;  ys,y,m : word);
  195. { This method initializes the amortization variables, and then runs EditData. }
  196. var  void : byte;
  197. begin
  198.   FirstYear   :=  y;
  199.   FirstMonth  :=  m;
  200.  
  201.   Total       :=  prin;
  202.   Rate        :=  interest / 100 / 12;
  203.   Years       :=  ys;
  204.   Periods     :=  Years * 12;
  205.   LastPayment :=  32000;
  206.  
  207.   Payment := AmortPMT (Total,Rate,Periods);
  208.  
  209.   Window (6,2,75,24);
  210.   WindBorder (LightCyan);
  211.  
  212.   TextAttr := bordercolor;
  213.   ClrScr;
  214.   GotoXY (2,23);
  215.   write ('F1 Help    Your monthly payment is:   $', Payment:1:2);
  216.   GotoXY (62,23);
  217.   write ('ESC Exit');
  218.   ClrPosition;  { reset current record pointer }
  219.   OpenBuffer (void, sizeof (AmortRec) * Periods);
  220.  
  221.   Repeat
  222.     EditData (void, Key,ext, [Esc],[F1]);
  223.     If ext = F1 then
  224.       ViewHelpWindow ('AMORT.HLP', 'B', 11,20,20,61, LightRed,$70);
  225.   Until (ext <> F1);
  226. end;
  227.  
  228.  
  229.   { ─────────────────────────────────────────────────────────────────────── }
  230.  
  231.  
  232. procedure SelectWindow.ZeroizeRecord (var Data );
  233. begin
  234.   { Do nothing, and ignore the ^Y command. }
  235. end;
  236.  
  237.  
  238.   { ─────────────────────────────────────────────────────────────────────── }
  239.  
  240.  
  241. procedure SelectWindow.EvaluateField (RecNum : longint;  CellNum,Line : word);
  242. begin
  243.   With Info [RecNum] do
  244.     begin
  245.     If Year = 0 then Year := 1990;
  246.     If (Month < 1) or (Month > 12) then Month := 1;
  247.     If Principal < 10 then Principal := 10.0;
  248.     If Interest <= 0 then Interest  := 10.0;
  249.     If Years < 2 then Years := 2;
  250.  
  251.     If (CellNum in [3..5]) or (Payment = 0.0) then
  252.       Payment := AmortPMT (Principal, (Interest / 100 / 12), Years * 12)
  253.      else
  254.       If CellNum = 6 then
  255.         Principal := AmortPRIN (Payment, (Interest / 100 / 12), Years * 12);
  256.  
  257.     DisplayRecord (Info [RecNum], Line);
  258.     end;
  259. end;
  260.  
  261.  
  262.   { ─────────────────────────────────────────────────────────────────────── }
  263.  
  264.  
  265. procedure SelectWindow.PickIt;
  266. var  i : word;
  267. begin
  268.   showzeroes  := True;  { make any zero amounts visible }
  269.   For i := 0 to 4 do
  270.     begin
  271.     With Info [i] do
  272.       begin
  273.       Year      := 1990;
  274.       Month     :=  1;
  275.       Principal := 10000.00;
  276.       Interest  := 10;
  277.       Years     := 30;
  278.       Payment   := AmortPMT (Principal, (Interest / 100 / 12), Years * 12);
  279.       end;
  280.     end;
  281.  
  282.   Repeat
  283.     Window (1,1,80,25);
  284.     TextAttr  := Black;
  285.     ClrScr;
  286.  
  287.     Window (10,7,71,15);
  288.     TextAttr  := bordercolor;
  289.     WindBorder (Yellow);
  290.     ClrScr;
  291.     GotoXY (3,9);
  292.     write ('F1 Help    F9 Amortize                             ESC Exit');
  293.  
  294.     OpenBuffer (Info, sizeof (Info));
  295.     Repeat
  296.       EditData (Info, Key,ext, [Esc],[F1,F9]);
  297.       If ext = F1 then
  298.         ViewHelpWindow ('AMORT.HLP', 'A', 12,30,24,78, LightRed,$70);
  299.     Until (ext <> F1);
  300.  
  301.     If (ext = F9) then With Info [currentrec] do
  302.       begin
  303.       AMORT.Amortize (Principal,Interest, Years,Year, Month - 1);
  304.       Key := #0;
  305.       end;
  306.   Until Key = Esc;
  307. end;  { PickIt }
  308.  
  309.  
  310.   { ─────────────────────────────────────────────────────────────────────── }
  311.  
  312.  
  313. Begin
  314.   DOScolors := TextAttr;  { save the original screen color }
  315.   TextAttr  := LightGray;
  316.   ClrScr;
  317.  
  318.   AMORT.Init (maintitle, baseformat, 2,2, $3B,$3F,$70);
  319.   SELECTOR.Init (spectitle, specformat, 2,2, $3E,$3F,$70);
  320.  
  321.   SELECTOR.Pickit;
  322.  
  323.   TextAttr := DOScolors;  { close the program in the original colors }
  324.   Window (1,1,80,25);
  325.   ClrScr;
  326. End.
  327.  
  328.